/*
 * UAE - The Un*x Amiga Emulator
 *
 * Interface to the graphics system (X, SVGAlib)
 *
 * Copyright 1995-1997 Bernd Schmidt
 */

#pragma once

typedef uint xcolnr;

typedef int (*allocfunc_type)(int, int, int, xcolnr*);

extern xcolnr xcolors[4096];
// extern xcolnr xcolors_16[4096];
// extern xcolnr xcolors_32[4096];
extern uint p96_rgbx16[65536];

extern int graphics_setup();
extern int graphics_init();
extern void graphics_leave();
extern void handle_events();
extern int handle_msgpump();
// extern void setup_brkhandler();
extern int isfullscreen();
extern void toggle_fullscreen(int);
extern void toggle_mousegrab();
// extern void desktop_coords(int* dw, int* dh, int* x, int* y, int* w, int* h);
extern bool vsync_switchmode(int);
extern bool vsync_busywait();
extern double vblank_calibrate(double, bool);
extern void doflashscreen();
extern int flashscreen;
extern void updatedisplayarea();

extern void flush_line(int);
extern void flush_block(int, int);
extern void flush_screen(int, int);
extern void flush_clear_screen();
extern bool render_screen();
extern void show_screen();

extern int lockscr(int);
extern void unlockscr();

// extern int debuggable();
extern void LED(int);
extern void screenshot(int, int);

extern int bits_in_mask(uint mask);
extern int mask_shift(uint mask);
extern uint doMask(int p, int bits, int shift);
extern uint doMask256(int p, int bits, int shift);
// extern void setup_maxcol(int);
// extern void alloc_colors256(int(*) (int, int, int, xcolnr*));
extern void alloc_colors64k(int, int, int, int, int, int, int, int, int, int);
extern void alloc_colors_rgb(int rw, int gw, int bw, int rs, int gs, int bs, int aw, int as, int alpha, int byte_swap,
    uint* rc, uint* gc, uint* bc);
extern void alloc_colors_picasso(int rw, int gw, int bw, int rs, int gs, int bs, int rgbfmt);
// extern void setup_greydither(int bits, allocfunc_type allocfunc);
// extern void setup_greydither_maxcol(int maxcol, allocfunc_type allocfunc);
// extern void setup_dither(int bits, allocfunc_type allocfunc);
// extern void DitherLine(byte* l, ushort* r4g4b4, int x, int y, short len, int bits);
extern double getvsyncrate(double hz);

struct vidbuf_description
{
    /* Function implemented by graphics driver */
    void (* flush_line)(struct vidbuf_description* gfxinfo, int line_no);
    void (* flush_block)(struct vidbuf_description* gfxinfo, int first_line, int end_line);
    void (* flush_screen)(struct vidbuf_description* gfxinfo, int first_line, int end_line);
    void (* flush_clear_screen)(struct vidbuf_description* gfxinfo);
    int (* lockscr)(struct vidbuf_description* gfxinfo);
    void (* unlockscr)(struct vidbuf_description* gfxinfo);

    /* The graphics code has a choice whether it wants to use a large buffer
     * for the whole display, or only a small buffer for a single line.
     * If you use a large buffer:
     *   - set bufmem to point at it
     *   - set linemem to 0
     *   - if memcpy within bufmem would be very slow, i.e. because bufmem is
     *     in graphics card memory, also set emergmem to point to a buffer
     *     that is large enough to hold a single line.
     *   - implement flush_line to be a no-op.
     * If you use a single line buffer:
     *   - set bufmem and emergmem to 0
     *   - set linemem to point at your buffer
     *   - implement flush_line to copy a single line to the screen
     */
    byte* bufmem, * bufmemend;
    byte* realbufmem;
    byte* linemem;
    byte* emergmem;
    bool bufmem_allocated;
    int rowbytes; /* Bytes per row in the memory pointed at by bufmem. */
    int pixbytes; /* Bytes per pixel. */
    int width;
    int height;
    int maxblocklines; /* Set to 0 if you want calls to flush_line after each drawn line, or the number of
                        * lines that flush_block wants to/can handle (it isn't really useful to use another
                        * value than maxline here). */
    int gfx_resolution_reserved; // reserved space for g_curr_conf.gfx_resolution
    int gfx_vresolution_reserved; // reserved space for g_curr_conf.gfx_resolution
};

extern struct vidbuf_description gfxvidinfo;

// /* For ports using tui.c, this should be built by graphics_setup(). */
// extern struct bstring* video_mode_menu;
// extern void vidmode_menu_selected(int);